﻿using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace mmCore.Common
{
	/// <summary>
	/// Klasa bazowa dla obiektów, które chcą implementować interfejs INotifyPropertyChanged,
	/// np. dla ViewModeli.
	/// Wyemitowanie zdarzenia informującego o zmianie wartości propertiesa publicznego 'A'
	/// sprowadza się do wykonania kodu:
	/// 
	/// RaisePropertyChanged(() => A);
	/// 
	/// </summary>
	public class NotifyPropertyChangedBase : INotifyPropertyChanged
	{
		public event PropertyChangedEventHandler PropertyChanged;

		public void RaisePropertyChanged(Expression<Func<object>> a_oPropertyExpression)
		{
			if (a_oPropertyExpression.NodeType != ExpressionType.Lambda)
			{
				throw new ArgumentException("Must be lambda!", "a_oPropertyExpression");
			}

			var body = a_oPropertyExpression.Body as MemberExpression;
			if (body == null)
			{
				var memberExpression = a_oPropertyExpression.Body as UnaryExpression;
				if (memberExpression != null)
				{
					body = memberExpression.Operand as MemberExpression;
					if (body == null)
					{
						throw new ArgumentException("'a_oPropertyExpression' should be a member expression");
					}
				}
				else
				{
					throw new ArgumentException("'a_oPropertyExpression' should be a member expression");
				}
			}

			string strPropertyName = body.Member.Name;

			PropertyChangedEventHandler oHandler = PropertyChanged;
			if (oHandler != null)
			{
				oHandler(this, new PropertyChangedEventArgs(strPropertyName));
			}
		}
	}
}
